#ifndef _Z_MULTICONN_CLIENT_H__
#define _Z_MULTICONN_CLIENT_H__

#include <zephyr/kernel.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/sys/slist.h>
#include <zephyr/bluetooth/uuid.h>

#ifdef __cplusplus
extern "C" {
#endif

// --- 配置选项 (来自 Kconfig, 示例) ---
// CONFIG_BT_MAX_CONN (Zephyr Kconfig)
// CONFIG_MULTICONN_CLIENT_MAX_SERVICES_PER_CONN (定义在 Kconfig)
// CONFIG_MULTICONN_CLIENT_MAX_CHARS_PER_SERVICE (定义在 Kconfig)
// CONFIG_MULTICONN_CLIENT_MAX_DESCS_PER_CHAR (定义在 Kconfig, 如果使能描述符发现)
// CONFIG_MULTICONN_CLIENT_CONN_PARAM_UPDATE_ENABLE (定义在 Kconfig)
// CONFIG_MULTICONN_CLIENT_DISCOVER_DESCRIPTORS_ENABLE (定义在 Kconfig)
// CONFIG_MULTICONN_CLIENT_LOG_LEVEL (定义在 Kconfig)


// 存储发现的描述符信息
typedef struct {
    sys_snode_t node;        // 用于链表
    struct bt_uuid_t uuid;   // 描述符 UUID (直接存储)
    uint16_t handle;       // 描述符句柄
} multiconn_descriptor_t;

// 存储发现的特征信息
typedef struct {
    sys_snode_t node;                 // 用于链表
    struct bt_uuid_t uuid;            // 特征 UUID (直接存储)
    uint16_t decl_handle;           // 特征声明句柄
    uint16_t value_handle;          // 特征值句柄
    uint8_t properties;             // 特征属性
    struct bt_gatt_subscribe_params sub_params; 
#ifdef CONFIG_MULTICONN_CLIENT_DISCOVER_DESCRIPTORS_ENABLE
    sys_slist_t descriptors;        // 存储该特征下的描述符链表 (multiconn_descriptor_t)
    uint8_t desc_count;             // 该特征下已发现的描述符数量
    uint16_t ccc_handle;            // 快捷方式: Client Characteristic Configuration Descriptor handle (如果找到)
#endif
} multiconn_characteristic_t;

// 存储发现的服务信息
typedef struct {
    sys_snode_t node;                 // 用于链表
    struct bt_uuid_t uuid;            // 服务 UUID (直接存储)
    uint16_t start_handle;          // 服务起始句柄
    uint16_t end_handle;            // 服务结束句柄
    sys_slist_t characteristics;        // 存储该服务下的特征链表 (multiconn_characteristic_t)
    uint8_t char_count;             // 该服务下已发现的特征数量
} multiconn_service_t;

// 连接上下文状态
typedef enum {
    MULTICONN_STATE_DISCONNECTED,
    MULTICONN_STATE_CONNECTED,
    MULTICONN_STATE_MTU_EXCHANGING,
#ifdef CONFIG_MULTICONN_CLIENT_CONN_PARAM_UPDATE_ENABLE
    MULTICONN_STATE_CONN_PARAM_UPDATING,
#endif
    MULTICONN_STATE_SERVICE_DISCOVERING,
    MULTICONN_STATE_CHAR_DISCOVERING,
#ifdef CONFIG_MULTICONN_CLIENT_DISCOVER_DESCRIPTORS_ENABLE
    MULTICONN_STATE_DESC_DISCOVERING,
#endif
    MULTICONN_STATE_READY,            // 初始化完成，准备好进行应用交互
    MULTICONN_STATE_ERROR             // 初始化过程中发生错误
} multiconn_state_t;

// 连接上下文，包含一个连接的所有状态和发现的数据
typedef struct multiconn_conn_context {
    struct bt_conn *conn;
    bool in_use;
    multiconn_state_t state;
    int last_err; // 记录最后一个错误码 (负数 errno 或正数 ATT 错误码)

    // GATT 操作参数 (库内部使用)
    struct bt_gatt_exchange_mtu_params mtu_params;
    struct bt_gatt_discover_params discover_params;

    // 存储发现结果
    sys_slist_t services; // 服务链表 (multiconn_service_t)
    uint8_t service_count;

    // 用于特征/描述符发现迭代
    sys_snode_t *current_service_node; // 指向当前正在进行操作的服务节点
    sys_snode_t *current_char_node;    // 指向当前正在进行操作的特征节点

    // 工作队列项，用于将 GATT 操作推迟到工作线程执行
    struct k_work work;

#ifdef CONFIG_MULTICONN_CLIENT_CONN_PARAM_UPDATE_ENABLE
    struct bt_conn_le_param desired_conn_params;
#endif

    // --- 注意: 线程安全 ---
    // 此结构体由库内部在蓝牙回调和系统工作队列线程中访问。
    // 如果应用层需要在 'ready' 或 'disconnected' 回调之外，
    // 从不同的线程并发访问或修改此结构体中的数据（尤其是发现的结果链表），
    // 应用层必须自行实现外部锁定机制（如 k_mutex）来保护访问。

} multiconn_conn_context_t;


// --- 回调函数 ---

// 定义应用层需要提供的回调函数结构
typedef struct {
    /**
     * @brief 当一个连接完成初始化序列（成功或失败）时调用
     * @param ctx 指向完成初始化的连接的上下文
     * @param err 0 表示成功, 负数 errno 值或正数 ATT 错误码表示失败
     */
    void (*ready)(struct multiconn_conn_context *ctx, int err);

    /**
     * @brief 当一个受管理的连接断开时调用
     * @param ctx 指向断开连接的上下文
     * @param reason 断开原因 (来自 Zephyr 回调)
     */
    void (*disconnected)(struct multiconn_conn_context *ctx, uint8_t reason);

    // 可以添加其他需要的 passthrough 回调, 如 security_changed

} multiconn_client_callbacks_t;


// --- 公开函数 ---

/**
 * @brief 初始化多连接客户端库
 *
 * @param callbacks 指向应用层提供的回调函数结构体。该指针在库的生命周期内必须有效。
 * @return 0 on success, negative errno code on failure.
 */
int multiconn_client_init(const multiconn_client_callbacks_t *callbacks);

/**
 * @brief (可选) 设置服务和特征UUID过滤器
 *
 * 如果调用此函数，库将只发现并存储列表中指定的服务和特征。
 * 如果不调用，默认发现所有主服务及其所有特征。
 * 必须在任何连接建立之前调用。
 *
 * @param svc_uuids 服务 UUID 数组。如果为 NULL 或 svc_count 为 0，则不进行服务过滤。
 * @param svc_count svc_uuids 数组中的元素数量。
 * @param char_uuids 特征 UUID 数组。如果为 NULL 或 char_count 为 0，则不进行特征过滤。
 * @param char_count char_uuids 数组中的元素数量。
 * @return 0 on success, -EINVAL if arguments are invalid.
 */
int multiconn_client_set_filter(const struct bt_uuid *svc_uuids[], size_t svc_count,
                                const struct bt_uuid *char_uuids[], size_t char_count);

/**
 * @brief 获取指定连接的上下文信息（包括状态和发现的数据）
 *
 * @param conn Zephyr 连接对象指针
 * @return 指向连接上下文的指针，如果未找到则返回 NULL
 */
struct multiconn_conn_context *multiconn_client_get_context(struct bt_conn *conn);

/**
 * @brief (辅助函数) 在给定服务的特征列表中查找具有特定UUID的特征。
 *
 * @param svc 指向已发现的服务结构体 (multiconn_service_t).
 * @param uuid 指向要查找的特征 UUID.
 * @return 指向找到的特征结构体 (multiconn_characteristic_t) 的指针，如果未找到则返回 NULL.
 */
multiconn_characteristic_t* multiconn_client_find_characteristic(multiconn_service_t *svc, const struct bt_uuid *uuid);

/**
 * @brief (辅助函数) 在给定特征的描述符列表中查找具有特定UUID的描述符。
 *
 * @param chara 指向已发现的特征结构体 (multiconn_characteristic_t).
 * @param uuid 指向要查找的描述符 UUID.
 * @return 指向找到的描述符结构体 (multiconn_descriptor_t) 的指针，如果未找到则返回 NULL.
 */
#ifdef CONFIG_MULTICONN_CLIENT_DISCOVER_DESCRIPTORS_ENABLE
multiconn_descriptor_t* multiconn_client_find_descriptor(multiconn_characteristic_t *chara, const struct bt_uuid *uuid);
#endif


#ifdef __cplusplus
}
#endif

#endif // _Z_MULTICONN_CLIENT_H__
